package com.cong.modules.job.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.cong.common.util.PageUtil;
import com.cong.common.util.UUIDUtil;
import com.cong.common.vo.AjaxResultVo;
import com.cong.modules.base.BaseController;
import com.cong.modules.job.model.SysJob;
import com.cong.modules.job.model.SysJobLog;
import com.cong.modules.job.service.SysJobLogService;
import com.cong.modules.job.service.SysJobService;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/sysJob")
public class SysJobController extends BaseController {

    @Resource
    private SysJobService sysJobService;

    @Resource
    private SysJobLogService sysJobLogService;

    /**
     * 系统工具--定时任务
     */
    @GetMapping("/toSysJobPage")
    public String sysjobList() {
        return "sysjob/list";
    }

    /**
     * 系统工具--定时任务日志
     */
    @GetMapping("/toSysJobLogPage")
    public String sysjobLogList() {
        return "sysjob/loglist";
    }

    /**
     * 系统工具--定时任务添加cron表达式
     */
    @GetMapping(value = "/tocron")
    public String tocron() {
        return "sysjob/cron";
    }

    /**
     * 查询定时任务列表
     *
     * @param sysJob 任务实体
     * @param limit 查询限制条数
     * @param offset 查询偏移值
     * @return 返回任务实体
     */
    @RequiresPermissions("sysJob:list")
    @PostMapping("/list")
    @ResponseBody
    public AjaxResultVo pageSysJob(SysJob sysJob, Integer limit, Integer offset, String daterange) {
        try {
            PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
            // 日期查询
            String[] dateranges = {};
            if (StringUtils.isNotBlank(daterange)) {
                dateranges = StringUtils.split(daterange, "~");
            }
            List<SysJob> jobList = sysJobService.listSysJobs(sysJob, dateranges);
            PageInfo<SysJob> pageResult = new PageInfo<>(jobList);
            AjaxResultVo resutlVo = AjaxResultVo.success();
            resutlVo.put("rows", pageResult.getList());
            resutlVo.put("total", pageResult.getTotal());
            return resutlVo;
        } catch (Exception e) {
            logger.error("定时任务列表查询失败 SysJobController.pageSysJob{}", e.getMessage());
            return AjaxResultVo.error("查询失败");
        }
    }

    /**
     * 跳转添加定时任务
     *
     * @return 跳转任务添加页面
     */
    @RequiresPermissions("sysJob:add")
    @GetMapping("/add")
    public String add() {
        return "sysjob/add";
    }

    /**
     * 添加定时任务
     *
     * @param sysJob 添加任务实体数据
     * @return 返回添加任务实体结果
     */
    @RequiresPermissions("sysJob:add")
    @PostMapping("/addSysJob")
    @ResponseBody
    public AjaxResultVo addSysJob(SysJob sysJob) {
        try {
            sysJob.setJobId(Long.valueOf(UUIDUtil.getUniqueIdByUUId()));
            Date currentDate = new Date();
            sysJob.setCreateTime(currentDate);
            sysJob.setUpdateTime(currentDate);
            int result = sysJobService.insertJob(sysJob);
            if (result > 0) {
                return AjaxResultVo.success("添加任务成功");
            } else {
                return AjaxResultVo.error("添加任务失败");
            }
        } catch (Exception e) {
            logger.error("定时任务添加失败 SysJobController.addSysJob{}", e.getMessage());
            return AjaxResultVo.error("添加任务失败");
        }
    }

    /**
     * 定时任务详情页
     *
     * @param model 跳转实体
     * @param jobId 任务ID
     * @return 返回任务详情
     */
    @RequiresPermissions("sysJob:edit")
    @GetMapping("/editSysJob")
    public String detail(Model model, String jobId) {
        SysJob sysJob = sysJobService.getSysJobById(Long.valueOf(jobId));
        model.addAttribute("sysJob", sysJob);
        return "sysjob/detail";
    }

    /**
     * 修改定时任务
     *
     * @param sysJob 修改任务实体数
     * @return 任务修改结果
     */
    @RequiresPermissions("sysJob:edit")
    @PostMapping("/editSysJob")
    @ResponseBody
    public AjaxResultVo editSysJob(@ModelAttribute("sysJob") SysJob sysJob) {
        try {
            Date currentDate = new Date();
            sysJob.setUpdateTime(currentDate);
            int result = sysJobService.updateJob(sysJob);
            if (result > 0) {
                return AjaxResultVo.success("编辑任务成功");
            } else {
                return AjaxResultVo.error("编辑任务失败");
            }
        } catch (Exception e) {
            logger.error("定时任务编辑失败 SysJobController.editSysJob{}", e.getMessage());
            return AjaxResultVo.error("编辑任务失败");
        }
    }

    /**
     * 批量删除定时任务
     *
     * @param jobIdStr 批量删除人事实体串
     * @return 返回任务批量删除结果
     */
    @RequiresPermissions("sysJob:delete")
    @PostMapping("/batchDelete")
    @ResponseBody
    public AjaxResultVo batchDelete(String jobIdStr) {
        try {
            sysJobService.deleteJobByIds(jobIdStr);
            return AjaxResultVo.success("删除成功");
        } catch (Exception e) {
            logger.error("定时任务批量删除失败 SysJobController.batchDelete{}", e.getMessage());
            return AjaxResultVo.error("删除失败");
        }
    }

    /**
     * 删除定时任务
     *
     * @param jobId 任务ID
     * @return 返回任务删除结果
     */
    @RequiresPermissions("sysJob:delete")
    @PostMapping("/deleteSysJob")
    @ResponseBody
    public AjaxResultVo delete(String jobId) {
        try {
            sysJobService.deleteJobByIds(jobId);
            return AjaxResultVo.success("删除成功");
        } catch (Exception e) {
            logger.error("定时任务单条删除失败 SysJobController.delete{}", e.getMessage());
            return AjaxResultVo.error("删除失败");
        }
    }

    /**
     * 批量删除定时任务日志
     *
     * @param jobLogIdStr 任务日志ID字符串
     * @return 返回批量日志删除结果
     */
    @RequiresPermissions("sysJob:delete")
    @PostMapping("/logBatchDelete")
    @ResponseBody
    public AjaxResultVo logBatchDelete(String jobLogIdStr) {
        try {
            sysJobLogService.deleteJobLogByIds(jobLogIdStr);
            return AjaxResultVo.success("删除成功");
        } catch (Exception e) {
            logger.error("定时任务日志批量删除失败 SysJobController.logBatchDelete{}", e.getMessage());
            return AjaxResultVo.error("删除失败");
        }
    }

    /**
     * 变更定时任务日志状态
     *
     * @param job 变更日志实体
     * @return 返回任务变更状态结果
     */
    @RequiresPermissions("sysJob:edit")
    @PostMapping("/changeStatus")
    @ResponseBody
    public AjaxResultVo changeStatus(SysJob job) {
        try {
            SysJob newJob = sysJobService.getSysJobById(job.getJobId());
            newJob.setStatus(job.getStatus());
            int result = sysJobService.changeStatus(newJob);
            if (result > 0) {
                return AjaxResultVo.success("修改成功");
            } else {
                return AjaxResultVo.error("修改失败");
            }
        } catch (Exception e) {
            logger.error("定时任务状态变更失败 SysJobController.changeStatus{}", e.getMessage());
            return AjaxResultVo.error("修改失败");
        }
    }

    /**
     * 运行定时任务
     *
     * @param job 运行定时任务实体
     * @return 定时任务运行结果
     */
    @RequiresPermissions("sysJob:edit")
    @PostMapping("/runSysJob")
    @ResponseBody
    public AjaxResultVo runSysJob(SysJob job) {
        try {
            sysJobService.run(job);
            return AjaxResultVo.success("任务运行成功");
        } catch (Exception e) {
            logger.error("定时任务运行失败 SysJobController.runSysJob{}", e.getMessage());
            return AjaxResultVo.error("任务运行失败");
        }
    }

    /**
     * corn表达式运行
     *
     * @param expression corn表达式
     * @return 返回表达式运行结果
     */
    @RequestMapping(value = "/calcRunTime")
    @ResponseBody
    public Object calcRunTime(String expression) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        StringBuffer sbResult = new StringBuffer();
        sbResult.append("[");
        try {
            CronTriggerImpl trigger = new CronTriggerImpl();
            trigger.setCronExpression(expression);
            Date start = trigger.getStartTime();
            for (int i = 0; i < 5; i++) {
                Date next = trigger.getFireTimeAfter(start);
                sbResult.append(", \"").append(sdf.format(next)).append("\"");
                start = next;
            }
            sbResult.append("]");
        } catch (ParseException e) {
            sbResult.append("cron表达式错误！");
            sbResult.append("]");
            return sbResult;
        }
        return sbResult.replace(sbResult.indexOf(","), sbResult.indexOf(",") + 1, "");
    }

    /**
     * 定时任务日志列表
     *
     * @param sysJobLog 系统日志实体
     * @param limit 查询限制条数
     * @param offset 查询游标值
     * @return 返回定时任务日志列表
     */
    @RequiresPermissions("sysJob:list")
    @PostMapping("/jobloglist")
    @ResponseBody
    public AjaxResultVo pageJobLogList(SysJobLog sysJobLog, Integer limit, Integer offset, String daterange) {
        try {
            PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
            // 日期查询
            String[] dateranges = {};
            if (StringUtils.isNotBlank(daterange)) {
                dateranges = StringUtils.split(daterange, "~");
            }
            List<SysJobLog> jobLogList = sysJobLogService.listSysLogJobs(sysJobLog, dateranges);
            PageInfo<SysJobLog> pageResult = new PageInfo<>(jobLogList);
            AjaxResultVo resultVo = AjaxResultVo.success();
            resultVo.put("rows", pageResult.getList());
            resultVo.put("total", pageResult.getTotal());
            return resultVo;
        } catch (Exception e) {
            logger.error("定时任务日志列表查询失败 SysJobController.pageJobLogList{}", e.getMessage());
            return AjaxResultVo.error("查询失败");
        }
    }

    /**
     * 定时任务运行详情
     *
     * @param model 跳转实体
     * @param jobLogId 任务日志ID
     * @return 任务日志详情
     */
    @GetMapping("/jobloginfo")
    public String jobLogInfo(Model model, String jobLogId) {
        SysJobLog sysJobLog = sysJobLogService.getSysJobLogById(Long.valueOf(jobLogId));
        model.addAttribute("sysJobLog", sysJobLog);
        return "sysjob/logdetail";
    }

}
